/**
  ******************************************************************************
  * @file
  * @brief
  * @author helei
  * @version V1.0.0
  * @date 2022/12/05
  ******************************************************************************
  */


/* Includes ------------------------------------------------------------------*/
#include "dev_dac8830.h"
#include "cmd_process.h"
#include "main_task.h"
#include "dev_ad7193_press.h"
#include "ParmManage.h"

extern SensorCalibration calibrations[];
/* Private defines -----------------------------------------------------------*/

/* Private Struct  -----------------------------------------------------------*/

/* Private enum    -----------------------------------------------------------*/

/* Private Variable  ---------------------------------------------------------*/
//Pointer

//Array

//Const

/* Private function prototypes -----------------------------------------------*/

 /***********************************************************************************
  * @brief Dac_PressConvertToVolt
  * ex:
  * @par  
  * None
  * @par 
  * None
  * @retval 
  **********************************************************************************/
 static float Dac8830_PressConvertToVolt(float target_press)
{
    float voltage = 0;
	static float k1 = 1;
	static float b1 = 0;
	static uint8_t firstIn = 1;
	
    if (firstIn)
    {
        // 读取校准系数
        PPItemRead(PP_DAC_CALI_K1, (uint8_t*)&k1, sizeof(float));
        PPItemRead(PP_DAC_CALI_B1, (uint8_t*)&b1, sizeof(float));

        // 对读取的值进行校验，避免非法值
        if (!isfinite(k1) || k1 == 0.0f) // isfinite 检查是否为有效数值
        {
            k1 = 1.0f; // 如果非法值则恢复默认
        }
        if (!isfinite(b1)) 
        {
            b1 = 0.0f; // 如果非法值则恢复默认
        }

    }
	
	k1 = (k1 == 0 ? 1:k1);
    b1 = (b1 == 0 ? 0:b1);
	//读取基体腔压力传感器的k和b,转换为电压
	
    voltage = (target_press -  calibrations[4].intercept) / calibrations[4].slope / PRESS_S1_COE;
	//voltage = 1.002948 * voltage + 0.003309;
	
	voltage = k1 * voltage + b1;
	//Ashell_print("dac k1:%f , b1:%f\r\n", k1, b1);
    return voltage;
 }

 /***********************************************************************************
  * @brief 
  * ex:
  * @par  
  * None
  * @par 
  * None
  * @retval 
  **********************************************************************************/
 void Dac8830_Write(dev_dac8830_t *this, float val, uint8_t ch)
 {
    uint16_t val_16 = (val / this->REF_V) * 65535;
    uint8_t write[2];
    uint8_t read[2];

    write[0] = val_16 >> 8;
    write[1] = val_16 & 0x00FF;


    this->private.spi.ReadWrite(&this->private.spi, write, read, 2);

    if(ch == 1){
     this->private.ch.Write(&this->private.ch, 0);
    }else{
     this->private.ch.Write(&this->private.ch, 1);
    }
 }

/***********************************************************************************
 * @brief 
 * ex:
 * @par  
 * None
 * @par 
 * None
 * @retval 
 **********************************************************************************/
void Dac8830_PressWrite(dev_dac8830_t *this, float target_press, uint8_t ch)
{

    float voltage = 0;
    uint16_t val_16 = 0;
    uint8_t write[2];
    uint8_t read[2];

    //压力转换为电压值
    voltage = Dac8830_PressConvertToVolt(target_press);
    //Ashell_print("target_press:%f press related vol:%f\r\n",target_press,voltage);
    
    //电压转换为码值
    val_16 = (voltage / this->REF_V) * 65535;
    
    write[0] = val_16 >> 8;
    write[1] = val_16 & 0x00FF;

    this->private.spi.ReadWrite(&this->private.spi, write, read, 2);
	
	if(ch == 1){
		this->private.ch.Write(&this->private.ch, 0);
	}else{
		this->private.ch.Write(&this->private.ch, 1);
	}
}

/***********************************************************************************
 * @brief    功能说明：初始化DAC8830 GPIO管脚、写函数配置
 * ex:
 * @par      输入参数：dev_dac8830_t *this - 待配置的DAC8830
 *           输出参数：dev_dac8830_t *this - GPIO、SPI、写函数配置完成的DAC8830
 * @retval   返回值：初始化配置成功返回0，否则返回-1
 **********************************************************************************/
int Dev_dac8830_Init(dev_dac8830_t *this)
{
    // SPI对象初始化
    this->private.spi.DRV       = this->DRV;
    this->private.spi.PIN_CS    = this->PIN_CS;
    this->private.spi.PIN_MOSI  = this->PIN_MOSI;
    this->private.spi.PIN_MISO  = NULL;
    this->private.spi.PIN_SCK   = this->PIN_SCK;
    this->private.spi.CS_EN     = SPI_CS_EN_L;
    this->private.spi.ORDER     = SPI_MSB;
    this->private.spi.CPOL      = SPI_CPOL_L;
    this->private.spi.CPHA      = SPI_CPHA_1;            //模式0 
    this->private.spi.TRANS     = SPI_TRANS_BYTE;
    this->private.spi.CS_DELAY_US = 1;
    if(Drv_Spi_Init(&this->private.spi) < 0){
        return -1;
    }
	
	// ch io config
	this->private.ch.PIN 			= this->PIN_CH;
	this->private.ch.MODE			= OUTPUT_UP;
	this->private.ch.INIT_LEVEL 	= HIGHT_LEVEL;
	if(Drv_Gpio_Init(&this->private.ch) < 0){
		return -1;
	}
	
    // 公共方法赋值
  this->Write = Dac8830_Write;
	this->PressWrite = Dac8830_PressWrite;

    return 0;
}



